package com.oig.sys.security.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.nimbusds.jose.shaded.json.JSONObject;
import com.oig.sys.security.support.SecurityUser;
import com.oig.sys.security.util.SecurityUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.convert.converter.Converter;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
import org.springframework.security.oauth2.jwt.Jwt;
import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;


/**
 * jwt时，解析jwt拿到用户的信息，这个也不好
 */
@Slf4j
public class CustomizeJwtAuthenticationConverter implements Converter<Jwt, AbstractAuthenticationToken> {

    private final JwtAuthenticationConverter jwtAuthenticationConverter = new JwtAuthenticationConverter();

    @Override
    public AbstractAuthenticationToken convert(Jwt jwt) {
        log.debug("jwt:{}", jwt);
        OAuth2AccessToken accessToken = new OAuth2AccessToken(OAuth2AccessToken.TokenType.BEARER, jwt.getTokenValue(),
                jwt.getIssuedAt(), jwt.getExpiresAt());
        Map<String, Object> attributes = jwt.getClaims();
        Object o = attributes.get(CacheConstants.ATTR_USER)  ;
        SecurityUser securityUser ;
        try {
            Map<?,?> obj = new HashMap<>();
            if (o instanceof JSONObject){
                JSONObject user = (JSONObject) o ;
                log.debug("user:{}", user.toJSONString());
                ObjectMapper objectMapper = new ObjectMapper();
                obj = objectMapper.readValue(objectMapper.writeValueAsString(user), Map.class);
            } else if (o instanceof Map){
                obj = (Map) o ;
            }
            securityUser = SecurityUtil.changeUser(obj);
        } catch (Exception e){
            throw new OAuth2AuthenticationException("无法转成 securityUser");
        }
        AbstractAuthenticationToken token = this.jwtAuthenticationConverter.convert(jwt);
        Collection<GrantedAuthority> authorities = token.getAuthorities();
        return new BearerTokenAuthentication(securityUser, accessToken, authorities);
    }
}
